#include "playcodevideo.h"

PlaycodeVideo::PlaycodeVideo()
    :QThread ()
{
    this->speed = 40;
    this->isRun = true;
    this->isStop = false;

    //获取摄像头
    //获取表中最后一行的设备信息
    char **qres=nullptr;
    int col=0,row=0;
    int res = ConfigureModel::getInstance()->selectLastConfigure(qres, row, col);
    if(res==0)
    {
//            for(int i=0;i<=row;i++)
//            {
//                qDebug() << i;
//            }
        this->cameraName = qres[1*col];
        qDebug() << "this->cameraName = " << this->cameraName;
//        this->mainwidget->getPlaycode()->setCamera(qres[1*col]);
    }

    this->encode = new EncodeVideo();
    connect(this->encode, SIGNAL(makeHeadTalier(QString)), this, SLOT(makeEncodeHeadTalier(QString)));
//    this->encoder = new EncodeVideo();
//    this->encoder->initEncode();
//    this->timer = new QTimer();

//    connect(timer, &QTimer::timeout, this, &PlaycodeVideo::onTimeout);
}

void PlaycodeVideo::initPlayCode()
{
    //输入输出设备注册
    avdevice_register_all();
    this->formatcontext = avformat_alloc_context();
    this->ifmt = av_find_input_format("dshow");
    int res = avformat_open_input(&this->formatcontext, QString("video=%1").arg(this->cameraName).toStdString().c_str(), this->ifmt, nullptr);

    //3.查找流媒体数据 判断码流数据
    res = avformat_find_stream_info(this->formatcontext, nullptr);
    if(res<0){
        qDebug()<< "find_stream fail";
    }
    else {
        qDebug() << "find_stream success";
    }
    this->video_index = -1;
    for(int i=0;i<this->formatcontext->nb_streams;i++){
        //nb_streams 有多少种码流数据的信息
        if(this->formatcontext->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
        {
            this->video_index = i;
            break;
        }
    }
    //如果下标还是-1，就没有找到
    if(this->video_index==-1){
        qDebug() << "video stream no find";
    }
    else {
        qDebug() << "video_index = " << this->video_index;
        qDebug() << "总帧数" << this->formatcontext->streams[this->video_index]->nb_frames;
    }
    //5.查找解码器
    this->codeccontext = this->formatcontext->streams[this->video_index]->codec;
    this->decoder = avcodec_find_decoder(this->codeccontext->codec_id);
    //判断是否找到了
    if(this->decoder==nullptr)
    {
        qDebug() << "decoder no find";
    }
    else {
        qDebug() << "decoder success";
    }
    //6.打开解码器
    res = avcodec_open2(this->codeccontext, this->decoder, nullptr);
    //判断是否成功
    if(res!=0)
    {
        qDebug() << "decoder open fail";
    }
    else {
        qDebug() << "decorder open success";
    }
    //7.读一帧数据
    //*******AVPacket准备工作*****************/
    this->packet = (AVPacket*)malloc(sizeof (AVPacket));
    int size = this->codeccontext->width * this->codeccontext->height;
    res = av_new_packet(this->packet,size);
    //判断是否成功
    if(res!=0)
    {
        qDebug() << "av_newpacket fail";
    }
    else {
        qDebug() << "av_newpacket success";
    }
    /********AVPacket准备工作...end*****************/

    this->encode->setWidth(this->codeccontext->width);
    this->encode->setHeight(this->codeccontext->height);

}

void PlaycodeVideo::initRGB()
{
    /*******AVFrame RGB准备工作  为了在窗口中播放显示、截图*********************/


    this->picture = av_frame_alloc();
    this->pictureRGB = av_frame_alloc();
    this->pictureRGB->width = this->codeccontext->width;
    this->pictureRGB->height = this->codeccontext->height;
    this->pictureRGB->format = this->codeccontext->pix_fmt;

    //设置缓冲区
    int imgByteRGB = avpicture_get_size(AV_PIX_FMT_RGB32,this->codeccontext->width, this->codeccontext->height);
    this->bufferRGB = (uint8_t*) av_malloc(imgByteRGB* sizeof(uint8_t));
    //填充
    avpicture_fill((AVPicture*)this->pictureRGB, this->bufferRGB, AV_PIX_FMT_RGB32,
                   this->codeccontext->width, this->codeccontext->height);

    //设置一个图像规则，
    //前三个参数都是原视频中一帧数据的宽度 高度 以及格式
    //中间三个参数是解码以后的一阵画面 宽度 高度 格式
    //转换数据的算法SWS_BICUBIC  余下三个nullptr
    this->swscontextRGB = sws_getContext(this->codeccontext->width, this->codeccontext->height, this->codeccontext->pix_fmt,
                                               this->codeccontext->width, this->codeccontext->height,AV_PIX_FMT_RGB32,
                                               SWS_BICUBIC, nullptr, nullptr, nullptr);

    /*******AVFrame RGB准备工作...end*******************/
}

void PlaycodeVideo::initYUV()
{
    /*******AVFrame YUV准备工作 为了后续的编码转码  YUV比RGB压缩率更高*************************/

    this->pictureYUV = av_frame_alloc();
    this->pictureYUV->width = this->codeccontext->width;
    this->pictureYUV->height = this->codeccontext->height;
    this->pictureYUV->format = this->codeccontext->pix_fmt;

    //设置缓冲区
    int imgByteYUV = avpicture_get_size(AV_PIX_FMT_YUV420P, this->codeccontext->width, this->codeccontext->height);
    this->bufferYUV = (uint8_t*) av_malloc(imgByteYUV* sizeof(uint8_t));

    avpicture_fill((AVPicture*)pictureYUV, this->bufferYUV, AV_PIX_FMT_YUV420P,
            this->codeccontext->width, this->codeccontext->height);

    this->swscontextYUV = sws_getContext(this->codeccontext->width, this->codeccontext->height, this->codeccontext->pix_fmt,
                                               this->codeccontext->width, this->codeccontext->height,AV_PIX_FMT_YUV420P,
                                               SWS_BICUBIC, nullptr, nullptr, nullptr);



    /*******AVFrame YUV准备工作...end*******************/
}

bool PlaycodeVideo::getIsRun() const
{
    return isRun;
}

void PlaycodeVideo::setIsRun(bool value)
{
    isRun = value;
}

bool PlaycodeVideo::getIsStop() const
{
    return isStop;
}

void PlaycodeVideo::setIsStop(bool value)
{
    isStop = value;
}

void PlaycodeVideo::run()
{

    int x= 0;
    while(this->isStop==false){
        if(this->isRun==true){
            if(av_read_frame(this->formatcontext,this->packet)==0)
            {
         //       if(this->isRun==true)
                if(this->packet->stream_index == this->video_index)
                {
                    //解码
                    int get_picture_ptr = -1;
                    //解码函数
                    avcodec_decode_video2(this->codeccontext, this->picture, &get_picture_ptr, this->packet);
                    if(get_picture_ptr!=0)
                    {
                        //---------------以下为了实现编码操作
                        //原视频avframe 转YUV数据格式的avframe
                        sws_scale(swscontextYUV, this->picture->data, this->picture->linesize, 0, this->picture->height,
                                this->pictureYUV->data, this->pictureYUV->linesize);        //数据格式转换

                        //编码线程开始了才存图片进队列
                        if(this->encode->getIsRun())
                        {
                            this->encode->queue.enqueue(this->pictureYUV);
                            qDebug()<<"this->encode->queue.size="<<this->encode->queue.size();
                        }

//                        this->encode = new EncodeVideo();

                        this->encode->start();


                        //------------------------以下操作为了在窗口UI中显示-------------------------------//
                        //原视频avframe 转RGB数据格式的avframe
                        sws_scale(swscontextRGB, this->picture->data, this->picture->linesize, 0, this->picture->height,
                                pictureRGB->data, pictureRGB->linesize);        //数据格式转换
                        img = QImage((uchar*)bufferRGB, codeccontext->width, codeccontext->height, QImage::Format_RGB32);
                        qDebug() << "x=" << x++;
                        //保存图片
                        //img.save(QString("../fileout/%1.jpg").arg(x));

                        //自定义信号发送图片给窗口
                        emit sendImg(img);

                        //毫秒为单位的延时 数值越大，播放速度越慢 播放倍速思维通过修改这个值来实现
                        msleep(this->speed);

                    }
                }

                //AVPacket包 清空
                av_packet_unref(packet);
            }
        }
    }
//            if(this->isRecord)
//                {
//                    //视频播放结束，循环结束后来一个写尾帧的操作
//                    this->encoder->writeTalier();
//                    this->isRecord = false;
//                }
//        }
//    }
//    if(this->isRecord)
//    {
//        //视频播放结束，循环结束后来一个写尾帧的操作
//        this->encoder->writeTalier();
//        this->isRecord = false;
//    }

    //解码器上下文关闭
    avcodec_close(this->codeccontext);
    //关闭文件
    avformat_close_input(&this->formatcontext);
}

void PlaycodeVideo::makeEncodeHeadTalier(QString(date))
{
//    //获取当前日期和时间
//    QDateTime currentDateTime = QDateTime::currentDateTime();
//    //获取当前时间
//    QTime currentTime = currentDateTime.time();
//    //获取当前日期
//    QDate currentDate = currentDateTime.date();
//    QString date = currentDateTime.toString("yyyy_MM_dd_hh_mm_ss");
//    QString datetime = currentDateTime.toString("yyyy-MM-dd hh:mm:ss");
//    QString filename = "../photo/" + date + ".jpg";
//    QString filename = date + ".jpg";
//    this->encode->videoPath = QString("%1/" + filename).arg(this->encode->videoPath);
//    this->img.save(QString("%2/%1").arg(filename).arg(this->encode->videoPath));
//    qDebug() << "PLayCode：" << this->encode->videoPath;
//    this->img.save(QString(this->encode->videoPath + "%1" + "jpg").arg(date));

    qDebug() << "PlayEncode：" << this->encode->videoPath;
    this->img.save(this->encode->videoPath);
}

